﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Noebe;
using Pixysoft.SQL;
using Pixysoft.Framework.Verifications;
using Pixysoft.Weblications.Sango.Formular;
using Pixysoft.Weblications.Sango.Entities;
using Pixysoft.Weblications.Sango.Environment;
using Pixysoft.Tools;
using Pixysoft.Weblications.Sango.Constant;

namespace Pixysoft.Weblications.Sango.Dao
{
    class MissionDao
    {
        // 用户任务记录表

        public static Entities.Usr_Mission getMission(string userCode)
        {
            IEntityNoebeCommand command = SettingHelper.GetNoebe().EntityNoebeCommand;
            command.SQL = (//
                    SqlCreator.SelectAll().From(Schemas.LOCAL.USR_MISSION)//
                            .Where(Schemas.LOCAL.USR_MISSION.USERCODE).Equal("USERCODE", true).GetSQL());
            command.Parameters.Add("USERCODE", userCode);

            List<Entities.Usr_Mission> orms = command.ExecuteReader<Entities.Usr_Mission>();

            if (orms.Count != 1)
                throw Exceptions.VerificationFailedException(userCode);

            return orms[0];
        }

        public static Entities.Usr_Mission createMission(string userCode, string nickname)
        {
            Entities.Usr_Mission orm = Entities.Local.Usr_Mission;
            orm.Primarycode = (PkHelper.PrimaryCode());
            orm.Usercode = (userCode);
            orm.Nickname = (nickname);
            orm.Globallastdate = (0);
            orm.Globalscorevalue = (0);
            orm.Globalrewarddate = (0);
            orm.Globaltypecode = (MissionFormular.getActivityTypeCode());
            orm.Dailylastdate = (0);
            orm.Dailymissionlist = (null);
            orm.Dailymaxlevel = (1);
            orm.Dailymissioncount = (0);

            refreshDailyMissionWeekly(orm);

            return orm;
        }

        // 每日任务

        /** 获取当前的每日任务 */
        public static DailyMissionItem getDailyMissionItem(Usr_Mission mission, string itemCode)
        {
            List<DailyMissionItem> items = getDailyMissions(mission);

            DailyMissionItem commitItem = trySearchDailyMission(items, itemCode);

            if (commitItem == null)
                throw Exceptions.VerificationFailedException(mission, itemCode);

            return commitItem;

        }

        /** 内部调用 重新每日任务统计信息 */
        public static void refreshDailyMissionWeekly(Entities.Usr_Mission mission)
        {
            List<DailyMissionItem> newitems = new List<DailyMissionItem>();

            long counter = 0;

            foreach (Mis_Dailymission item in MissionHelper.initializeDailyMissions())
            {
                counter++;
                DailyMissionItem newitem = new DailyMissionItem();
                newitem.ItemCode = counter.ToString();
                newitem.Status = GeneralBillStatusCollection.NEW;
                newitem.MissionTypeCode = (item.Missiontypecode);

                newitem.FinishCount = (0);
                newitem.Level = (1);
                newitems.Add(newitem);
            }

            setDailyMissions(mission, newitems);

            mission.Dailymissioncount = (0);

            mission.Dailymaxlevel = (1);

            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());
        }

        /** 对象转字段 */
        private static void setDailyMissions(Usr_Mission mission, List<DailyMissionItem> list)
        {
            // itemcode:typecode:status:finishcount:level;

            StringBuilder builder = new StringBuilder();
            foreach (DailyMissionItem item in list)
                builder.Append(string.Format("{0}:{1}:{2}:{3}:{4};",
                        item.ItemCode, item.MissionTypeCode, item.Status,//
                        item.FinishCount, item.Level));
            mission.Dailymissionlist = (builder.ToString());
            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());
        }

        /** 每日任务当前最高等级 */
        public static long getDailyMissionMaxLevel(Usr_Mission mission)
        {
            long level = -1;

            List<DailyMissionItem> items = getDailyMissions(mission);

            foreach (DailyMissionItem item in items)
            {
                if (item.Level > level)
                    level = item.Level;
            }

            return level;
        }

        /// <summary>
        /// 每日重置任务 
        /// </summary>
        /// <param name="activity"></param>
        public static void refreshDailyMissionDaily(Usr_Mission mission)
        {
            mission.Dailymissioncount = (0);
        }

        /// <summary>
        /// 任务模块 用户接收每日事件
        /// </summary>
        /// <param name="activity"></param>
        /// <param name="itemCode"></param>
        /// <returns></returns>
        public static bool acceptDailyMission(Usr_Mission mission, string itemCode)
        {
            if (mission.Dailymissioncount >= MissionFormular.default_max_dailymission)
                return false;

            bool founded = false;

            List<DailyMissionItem> items = getDailyMissions(mission);

            foreach (DailyMissionItem item in items)
            {
                if (item.Status == GeneralBillStatusCollection.ACCEPT)
                {
                    item.Status = (GeneralBillStatusCollection.NEW);
                }

                if (item.ItemCode.Equals(itemCode, StringComparison.OrdinalIgnoreCase))
                {
                    item.Status = (GeneralBillStatusCollection.ACCEPT);

                    founded = true;
                }
            }

            setDailyMissions(mission, items);

            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());

            return founded;
        }

        /// <summary>
        /// 任务模块 用户取消接收每日事件 事件不存在 返回false
        /// </summary>
        /// <param name="activity"></param>
        public static void cancelDailyMission(Usr_Mission mission)
        {
            List<DailyMissionItem> items = getDailyMissions(mission);

            foreach (DailyMissionItem item in items)
            {
                if (item.Status == GeneralBillStatusCollection.ACCEPT)
                    item.Status = (GeneralBillStatusCollection.NEW);
            }

            setDailyMissions(mission, items);

            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());
        }

        /** 内部调用 处理每日任务 处理失败返回false 不是外部指定code操作 */
        public static bool processDailyMission(Usr_Mission mission, long typeCode)
        {
            List<DailyMissionItem> items = getDailyMissions(mission);

            DailyMissionItem item = trySearchDailyMission(items, typeCode);

            if (item == null)
                return false;

            item.FinishCount = (item.FinishCount + 1);

            if (item.FinishCount >= item.Level)
            {
                item.Status = (GeneralBillStatusCollection.FINISH);
            }

            setDailyMissions(mission, items);

            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());

            return true;
        }

        /** 提交当前任务 如果所有任务等级相同，则提高一个等级 否则等级不变 */
        public static bool commitDailyMission(Usr_Mission mission, string itemCode)
        {
            List<DailyMissionItem> items = getDailyMissions(mission);

            DailyMissionItem commitItem = trySearchDailyMission(items, itemCode);

            if (commitItem == null)
                throw Exceptions.VerificationFailedException(mission, itemCode);

            // 判断是否完成

            if (commitItem.Status != GeneralBillStatusCollection.FINISH)
                return false;

            // 判断是否到达每日最大限额

            if (mission.Dailymissioncount >= MissionFormular.default_max_dailymission)
                return false;

            // 设置当日完成的最大星级任务等级

            long maxLevel = mission.Dailymaxlevel;

            long itemLevel = commitItem.Level;

            if (itemLevel > maxLevel)
            {
                maxLevel = itemLevel;

                mission.Dailymaxlevel = (maxLevel);
            }

            // 当前任务升级

            if (canDailyMissionUpgradeLevel(items, commitItem))
            {
                commitItem.Level = (commitItem.Level + 1);
            }

            // 重设状态

            foreach (DailyMissionItem item in items)
            {
                item.Status = (GeneralBillStatusCollection.NEW);
                item.FinishCount = (0);
            }

            setDailyMissions(mission, items);

            mission.Dailylastdate = (GlobalTimer.Instance.ToTimeSequence());

            mission.Dailymissioncount = (mission.Dailymissioncount + 1);

            return true;
        }

        /// <summary>
        /// 当前项目是否可以升级 如果所有等级一致/当前等级小于最高等级，则可以
        /// </summary>
        /// <param name="items"></param>
        /// <param name="selectedItem"></param>
        /// <returns></returns>
        private static bool canDailyMissionUpgradeLevel(List<DailyMissionItem> items, DailyMissionItem selectedItem)
        {
            if (selectedItem.Level >= MissionFormular.default_max_dailymission_level)
                return false;

            long formerLevel = items[0].Level;

            long maxLevel = formerLevel;

            bool allEqual = true;

            for (int i = 1; i < items.Count; i++)
            {
                long currentlevel = items[i].Level;

                if (formerLevel != currentlevel)
                {
                    allEqual = false;
                }

                if (currentlevel > maxLevel)
                    maxLevel = currentlevel;
            }

            if (allEqual)
            {
                return MissionFormular.canDailyMissionUpgrade(selectedItem.Level);
            }

            if (selectedItem.Level < maxLevel)
                return MissionFormular.canDailyMissionUpgrade(selectedItem.Level);

            return false;
        }

        private static DailyMissionItem trySearchDailyMission(List<DailyMissionItem> items, long typeCode)
        {
            foreach (DailyMissionItem item in items)
            {
                if (item.Status != GeneralBillStatusCollection.ACCEPT)
                    continue;

                if (item.MissionTypeCode != typeCode)
                    continue;

                return item;
            }

            return null;
        }

        private static DailyMissionItem trySearchDailyMission(List<DailyMissionItem> items, string itemCode)
        {
            foreach (DailyMissionItem item in items)
            {
                if (item.ItemCode.Equals(itemCode, StringComparison.OrdinalIgnoreCase))
                    return item;
            }

            return null;
        }

        /// <summary>
        /// 字段转对象
        /// </summary>
        /// <param name="activity"></param>
        /// <returns></returns>
        public static List<DailyMissionItem> getDailyMissions(Usr_Mission mission)
        {
            List<DailyMissionItem> list = new List<DailyMissionItem>();

            if (string.IsNullOrEmpty(mission.Dailymissionlist))
                return list;

            foreach (string item in mission.Dailymissionlist.Split(new char[] { ';' }))
            {
                if (string.IsNullOrEmpty(item))
                    continue;

                string[] itemdetail = item.Split(new char[] { ':' });

                if (itemdetail.Length != 5)
                    continue;

                // itemcode:typecode:status:finishcount:level;

                DailyMissionItem aitem = new DailyMissionItem();

                aitem.ItemCode = (itemdetail[0]);
                aitem.MissionTypeCode = (int.Parse(itemdetail[1]));
                aitem.Status = (int.Parse(itemdetail[2]));

                aitem.FinishCount = (int.Parse(itemdetail[3]));
                aitem.Level = (int.Parse(itemdetail[4]));

                list.Add(aitem);
            }

            return list;
        }





        // 主线任务

        /// <summary>
        /// 初始化用户主线任务列表
        /// </summary>
        /// <param name="usercode"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public static List<Usr_Mainmission> initializeMainmissions(string usercode, string username)
        {
            List<Usr_Mainmission> list = new List<Usr_Mainmission>();

            foreach (Entities.Mis_Mainmission main in MissionHelper.getNextMainMissions(MissionFormular.MAINMISSION_ROOT))
            {
                list.Add(createMainmission(main, usercode, username));
            }

            return list;
        }

        /// <summary>
        /// 根据任务原型创建用户主线任务
        /// </summary>
        /// <param name="mission"></param>
        /// <param name="usercode"></param>
        /// <param name="nickname"></param>
        /// <returns></returns>
        private static Usr_Mainmission createMainmission(Entities.Mis_Mainmission mission, string usercode, string nickname)
        {
            Usr_Mainmission orm = Local.Usr_Mainmission;
            orm.Primarycode = (PkHelper.PrimaryCode());
            orm.Usercode = (usercode);
            orm.Nickname = (nickname);
            orm.Missionserialcode = (mission.Serialcode);
            orm.Missionstatus = (GeneralBillStatusCollection.NEW);
            return orm;
        }

        /// <summary>
        /// 获取用户新建的主线任务列表 用于处理
        /// </summary>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public static List<Usr_Mainmission> getNewUsrMainMissions(string userCode)
        {
            // 搜索用户主线任务日志

            IEntityNoebeCommand command = SettingHelper.GetNoebe().EntityNoebeCommand;
            command.SQL = (//
                    SqlCreator.SelectAll().From(Schemas.LOCAL.USR_MAINMISSION)//
                            .Where(Schemas.LOCAL.USR_MAINMISSION.USERCODE).Equal("USERCODE", true)//
                            .And(Schemas.LOCAL.USR_MAINMISSION.MISSIONSTATUS).Equal("MISSIONSTATUS", true).GetSQL());
            command.Parameters.Add("USERCODE", userCode);
            command.Parameters.Add("MISSIONSTATUS", GeneralBillStatusCollection.NEW);

            List<Usr_Mainmission> orms = command.ExecuteReader<Usr_Mainmission>();

            return orms;
        }

        /// <summary>
        /// 获取用户可见的主线任务列表
        /// </summary>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public static List<Usr_Mainmission> getUsrMainMissions(string userCode)
        {
            // 搜索用户主线任务日志

            IEntityNoebeCommand command = SettingHelper.GetNoebe().EntityNoebeCommand;
            command.SQL = (//
                    SqlCreator.SelectAll().From(Schemas.LOCAL.USR_MAINMISSION)//
                            .Where(Schemas.LOCAL.USR_MAINMISSION.USERCODE).Equal("USERCODE", true)//
                            .And(Schemas.LOCAL.USR_MAINMISSION.MISSIONSTATUS).NotEqual("MISSIONSTATUS", true).GetSQL());
            command.Parameters.Add("USERCODE", userCode);
            command.Parameters.Add("MISSIONSTATUS", GeneralBillStatusCollection.CLOSE);

            List<Usr_Mainmission> orms = command.ExecuteReader<Usr_Mainmission>();

            return orms;
        }

        /// <summary>
        /// 根据手工编码搜索主线任务
        /// </summary>
        /// <param name="userCode"></param>
        /// <param name="serialCode"></param>
        /// <returns></returns>
        public static Usr_Mainmission getUsrMainmission(string userCode, long serialCode)
        {
            IEntityNoebeCommand command = SettingHelper.GetNoebe().EntityNoebeCommand; ;
            command.SQL = (//
                    SqlCreator.SelectAll().From(Schemas.LOCAL.USR_MAINMISSION)//
                            .Where(Schemas.LOCAL.USR_MAINMISSION.USERCODE).Equal("USERCODE", true)//
                            .And(Schemas.LOCAL.USR_MAINMISSION.MISSIONSERIALCODE).Equal("serialcode", true)//
                            .And(Schemas.LOCAL.USR_MAINMISSION.MISSIONSTATUS).NotEqual("MISSIONSTATUS", true).GetSQL());
            command.Parameters.Add("USERCODE", userCode);
            command.Parameters.Add("serialcode", serialCode);
            command.Parameters.Add("MISSIONSTATUS", GeneralBillStatusCollection.CLOSE);

            List<Usr_Mainmission> orms = command.ExecuteReader<Usr_Mainmission>();

            if (orms.Count != 1)
                return null;

            return orms[0];
        }

        /// <summary>
        /// 切面操作 处理主线任务中的主动任务 有多情况
        /// </summary>
        /// <param name="mission"></param>
        public static void finishMainMission(Usr_Mainmission mission)
        {
            mission.Missionstatus = (GeneralBillStatusCollection.FINISH);
        }

        /// <summary>
        /// 任务模块 获取指定的主线任务 不存在则异常 
        /// </summary>
        /// <param name="missions"></param>
        /// <param name="serialcode"></param>
        /// <returns></returns>
        public static Usr_Mainmission trySearchMainMission(List<Usr_Mainmission> missions, long serialcode)
        {
            foreach (Usr_Mainmission mission in missions)
            {
                if (mission.Missionserialcode == serialcode)
                    return mission;
            }

            return null;
        }

        /// <summary>
        /// 主线任务 玩家确认当前主线任务 激发下一个主线任务(状态为new) 如果任务容量达到最大，则激发失败
        /// </summary>
        /// <param name="mission"></param>
        public static void commitMainMission(Usr_Mainmission mission)
        {
            mission.Missionstatus = (GeneralBillStatusCollection.CLOSE);
        }

        /// <summary>
        /// 主线任务 获取当前类型下的下一步开放主线活动
        /// </summary>
        /// <param name="usercode"></param>
        /// <param name="username"></param>
        /// <param name="serialcode"></param>
        /// <returns></returns>
        public static List<Usr_Mainmission> searchOpenMissions(string usercode, string username, long serialcode)
        {
            List<Usr_Mainmission> list = new List<Usr_Mainmission>();

            foreach (Entities.Mis_Mainmission main in MissionHelper.getNextMainMissions(serialcode))
            {
                list.Add(createMainmission(main, usercode, username));
            }

            return list;
        }



        // 全局任务

        /** 任务模块 刷新游戏总活动 */
        protected static void refreshGlobalMission(Entities.Usr_Mission activity)
        {
            activity.Globalrewarddate = (GlobalTimer.Instance.ToTimeSequence());
            activity.Globallastdate = (activity.Globallastdate);
            activity.Globalscorevalue = (0);
            activity.Globaltypecode = (MissionFormular.default_max_dailymission);
        }


    }


    public class DailyMissionItem
    {
        // 任务编码 内存生成顺序序列
        string itemCode;
        // 类型编码 根据常量表配置
        long typeCode;
        // 任务状态
        long status;
        // 每日任务等级
        long level;
        // 每日任务完成情况
        long finishCount;

        public string ItemCode
        {
            get { return itemCode; }
            set { itemCode = value; }
        }
        public long MissionTypeCode
        {
            get { return typeCode; }
            set { typeCode = value; }
        }
        public long Status
        {
            get { return status; }
            set { status = value; }
        }
        public long Level
        {
            get { return level; }
            set { level = value; }
        }
        public long FinishCount
        {
            get { return finishCount; }
            set { finishCount = value; }
        }





    }
}
